﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.DirectoryServices;
using System.Management;
using System.IO;
using System.Text.RegularExpressions;

namespace ADAuthTest
{
    class Program
    {
        private const string USER_PROPERTY_NAME = "displayName";
        private const string USER_PROPERTY_USERNAME = "sAMAccountName";
        private const string distinguishedName = "distinguishedName";
        private const string gPLink = "gPLink";
        private const string gPCFileSysPath = "gPCFileSysPath";
        private const string LDAPHead = "LDAP://ceibs.edu";
        private const string LDAPRoot = "LDAP://ceibs.edu/CN=Users,DC=ceibs,DC=edu";

        static string UserName = "moss2010";
        static string Password = "JDP93fv";

        //static string UserName = "FacTest3";
        //static string Password = "abc.123";

        //static string UserName = "factest2";
        //static string Password = "abc.123";

        static string GetPcPath()
        {
            string distinguished = GetUserDistinguishedNameByAD();
            if (string.IsNullOrEmpty(distinguished))
                return string.Empty;

            int m = distinguished.IndexOf(",") + 1;
            string gplinkPath = string.Format("{0}/{1}", LDAPHead, distinguished.Substring(m));
            string gplink = GetDirctoryPathProperty(gplinkPath, gPLink);
            if (string.IsNullOrEmpty(gplink))
                return string.Empty;

            gplink = gplink.Replace("[LDAP://", "");
            int nIndex = gplink.LastIndexOf(";");
            string gpcFileSysPath = string.Format("{0}/{1}", LDAPHead, gplink.Substring(0, nIndex));
            string pcPath = GetDirctoryPathProperty(gpcFileSysPath, gPCFileSysPath);
            if (string.IsNullOrEmpty(pcPath))
                return string.Empty;

            return string.Format("{0}\\User\\Scripts", pcPath);
        }
        static void ListDrivePath()
        {
            string path = GetBatFile();
            //string[] files = Directory.GetFiles(path, "*.bat", SearchOption.TopDirectoryOnly);

            using (StreamReader sr = new StreamReader(path))
            {
                string text = sr.ReadToEnd();

                //if (!text.Contains(UserName))
                //    continue;
                string regBat = @"^net use (\w):\s?(\\\\.*)$";
                GetDrivePath(text, regBat);
                string regVBA = @"^WshNetwork.MapNetworkDrive\s?""(\w):\"",""(\\\\.*)""$";
                GetDrivePath(text, regVBA);
            }

        }
        static void GetDrivePath(string text,string expression)
        {
            Regex regex = new Regex(expression, RegexOptions.IgnoreCase | RegexOptions.Multiline);
            MatchCollection matchCollection = regex.Matches(text);
            foreach (Match match in matchCollection)
            {
                if (match.Groups[1].Success && match.Groups[2].Success)
                {
                    string drive = match.Groups[1].Value;
                    string netPath = match.Groups[2].Value;
                    Console.WriteLine(string.Format("{0}:{1}", drive, netPath));
                }
            }
        }
        static string GetBatFile()
        {
            string path = GetPcPath();
            if (string.IsNullOrEmpty(path))
                return string.Empty;
            try
            {
                using (StreamReader scriptSR = new StreamReader(string.Format("{0}\\scripts.ini", path)))
                {
                    string scriptText = scriptSR.ReadToEnd();
                    Regex regex = new Regex(@"0CmdLine=(\w+.(bat|VBS))", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant | RegexOptions.Multiline);
                    MatchCollection mc = regex.Matches(scriptText);
                    if (mc.Count > 0 && mc[0].Groups[1].Success)
                    {
                        string batName = mc[0].Groups[1].Value;
                        return string.Format("{0}\\User\\Scripts\\Logon\\{1}", path, batName);
                    }
                    return string.Empty;
                }
            }
            catch
            {
                return string.Empty;
            }
        }
        static void Main(string[] args)
        {
            //SharePointUser sp = new SharePointUser();
            //string ServerName = "LDAP://ceibs.edu/CN=Users,DC=ceibs,DC=edu";
            //string UserName = "ceibs\\moss2010";
            //string Password = "JDP93fv";

            //UserName = Console.ReadLine();
            try
            {
                //GetUserFullNameByAD("ceibs\\FacTest1", "abc.123");

                Console.WriteLine("PC path:" + GetPcPath());
                //ListDrivePath();
                Console.Read();


            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                Console.WriteLine(ex.StackTrace);
            }

            Console.Read();
        }
        public static void GetProfile(string path, string username, string password)
        {
            using (DirectoryEntry root = new DirectoryEntry(path, username, password))
            {
                OutPut(root);

            }
        }
        public static string GetUserFullNameByAD(string alias, string password)
        {
            if (String.IsNullOrEmpty(alias) || !alias.Contains('\\'))
                return "(unknown)";

            using (DirectoryEntry root = new DirectoryEntry(
                String.Format("LDAP://{0}.edu", alias.Split('\\')[0])))
            {
                root.Username = alias;
                root.Password = password;

                //DirectoryEntry user = new DirectoryEntry("CN=FacTest3,OU=MultDrive,OU=CEIBS Users,DC=CEIBS,DC=EDU",alias,password);

                using (DirectorySearcher ds = new DirectorySearcher(root))
                {
                    ds.Filter = String.Format(
                        "(&(objectCategory=person)(objectClass=user)({0}={1}))",
                         USER_PROPERTY_USERNAME,
                         alias.Split('\\')[1]);
                    //ds.Filter = "(&(objectClass=groupPolicyContainer))";
                    //GetProfile("LDAP://ceibs.edu/OU=MultDrive,OU=CEIBS Users,DC=CEIBS,DC=EDU", alias, password);
                    GetProfile("LDAP://ceibs.edu/cn={5A17CC0E-52A9-432D-A48E-CBA65F9EA46F},cn=policies,cn=system,DC=CEIBS,DC=EDU", alias, password);
                    //GetProfile("LDAP://ceibs.edu/cn={5A17CC0E-52A9-432D-A48E-CBA65F9EA46F},cn=policies,cn=system,DC=ceibs,DC=edu", alias, password);
                    try
                    {
                        SearchResult sr = ds.FindOne();
                        if (sr == null)
                            return "(unknown user)";
                        OutPut(sr.GetDirectoryEntry());
                        //if(sr.Properties[USER_PROPERTY_NAME].Count>0)
                        //    return sr.Properties[USER_PROPERTY_NAME][0].ToString();
                        //else
                        return "(unknown)";
                    }
                    catch (DirectoryServicesCOMException)
                    {
                        return "(unknown)";
                    }
                }
            }
        }
        private static void OutPut(DirectoryEntry de)
        {

            foreach (var item in de.Properties.PropertyNames)
            {
                try
                {
                    string propertyName = item.ToString();
                    string propertyValue = de.Properties[propertyName].Value.ToString();
                    Console.WriteLine(string.Format("{0}:{1}", propertyName, propertyValue));
                    //Response.Write(string.Format("{0}:{1}<br/>",propertyName,propertyValue));
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                    Console.WriteLine(ex.StackTrace);
                }
            }
        }

        private static string GetUserDistinguishedNameByAD()
        {
            using (DirectoryEntry root = new DirectoryEntry(LDAPHead))
            {
                root.Username = UserName;
                root.Password = Password;
                using (DirectorySearcher ds = new DirectorySearcher(root))
                {
                    ds.Filter = String.Format(
                        "(&(objectCategory=person)(objectClass=user)({0}={1}))",
                         USER_PROPERTY_USERNAME,
                         "zchun");

                    try
                    {
                        SearchResult sr = ds.FindOne();
                        if (sr == null)
                            return string.Empty;
                        object propertyValue = null;
                        if (sr.Properties.Contains(distinguishedName) && sr.Properties[distinguishedName].Count > 0)
                        {
                            propertyValue = sr.Properties[distinguishedName][0];
                        }

                        if (propertyValue != null)
                            return propertyValue.ToString();
                        else
                            return string.Empty;
                    }
                    catch (DirectoryServicesCOMException)
                    {
                        return string.Empty;
                    }
                }
            }
        }
        private static string GetDirctoryPathProperty(string path, string propertyName)
        {
            using (DirectoryEntry root = new DirectoryEntry(path, UserName, Password))
            {
                object propertyValue = null;
                if (root.Properties.Contains(propertyName))
                    propertyValue = root.Properties[propertyName].Value;

                if (propertyValue != null)
                    return propertyValue.ToString();
                else
                    return string.Empty;
            }
        }

    }
}
